import Vue from 'vue'
import axios from 'axios'
import { notification, Loading } from 'element-ui'
import { VueAxios } from './axios'
import apiAddress from '@/api/api'
import { replaceParam } from '@/utils/decryptByDES'
import _ from 'lodash'
// import router from '@/router'

// 取消拦截请求
const noInterUrls = Object.keys(apiAddress).filter(url => {
  return url !== 'realTimeMonitorOrgs'
})

function getBaseUrl () {
  return Vue.prototype.BASE_URL || ''
}

function getcsrf () {
  return Vue.prototype._csrf
}

// 创建 axios 实例
const service = axios.create({
  timeout: 60000, // 请求超时时间
  withCredentials: true // 是否携带cookies发起请求
})

// 这里开始防止重复请求
const removePending = ever => {
  for (const p in window.pending) {
    const pending = window.pending[p]
    if (pending.u === ever.url + '&' + ever.method + '&' + JSON.stringify(ever.params) + '&' + JSON.stringify(ever.data)) {
      // 当当前请求在数组中存在时执行函数体
      try {
        pending.f() // 执行取消操作
        window.pending.splice(p, 1) // 把这条记录从数组中移除
      } catch (e) {
        console.log(e)
      }
    }
  }
}

// 这里开始全局loading
/* 当页面有两个接口时，第一个接口loading的close事件会直接将第二个接口的loading实例也close */
let loadingInstance = null // 设置全局变量loading

function startLoading (dom) {
  loadingInstance = Loading.service({
    target: dom || 'body',
    background: 'rgba(255, 255, 255, 0.7)',
    customClass: 'v-loading',
    spinner: 'iconfont icon-weibiaoti-3',
    text: '加载中.'
  })
}

// 关闭loading状态
const endLoading = _.debounce(() => {
  loadingInstance.close()
  loadingInstance = null
}, 300)

let needLoadingRequestCount = 0 // 设置全局的请求总数

function showScreenLoading () {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}
function hideScreenLoading () {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}

const err = error => {
  hideScreenLoading()
  if (error.response) {
    const data = error.response.data || {}
    if (error.response.status === 403) {
      notification.error({
        message: '禁止访问,请重新登陆',
        description: data.message
      })
    } else {
      notification.error({
        message: error.response.status,
        description: data.message || '接口请求异常'
      })
    }
  }
  return Promise.reject(error)
}

// request interceptor
service.interceptors.request.use(config => {
  // 去除空对象
  if (config.params) {
    config.params = _.pickBy(config.params, (value) => {
      return !!value || value === 0 || value === false
    })
  }
  if (config.data && Object.prototype.toString.call(config.data) !== '[object FormData]') {
    config.data = _.pickBy(config.data, (value) => {
      return !!value || value === 0 || value === false
    })
  }

  if (config.headers.showLoading) {
    showScreenLoading(config.headers.dom)
  }
  // 不为对象传输
  if (config.data && config.data.bodyType) {
    config.data = config.data.key
  }
  config.headers['X-Requested-With'] = 'XMLHttpRequest'
  config.baseURL = getBaseUrl()
  const csrf = getcsrf()
  if (csrf) {
    config.headers['X-XSRF-TOKEN'] = csrf
  }
  // ------------------------------------------------------------------------------------
  removePending(config) // 在一个ajax发送前执行一下取消操作
  config.cancelToken = new axios.CancelToken(cancel => {
    // 这里的ajax标识我是用请求地址&请求方式拼接的字符串，当然你可以选择其他的一些方式
    // 判断是否拦截
    const interReq = [
      ...noInterUrls
    ]
    if (!interReq.includes(config.url)) {
      window.pending.push({ u: config.url + '&' + config.method + '&' + JSON.stringify(config.params) + '&' + JSON.stringify(config.data), f: cancel })
    }
  })
  // -----------------------------------------------------------------------------------------
  return config
}, err)

// response interceptor
service.interceptors.response.use(response => {
  hideScreenLoading()
  // ------------------------------------------------------------------------------------------
  removePending(response.config) // 在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
  // -------------------------------------------------------------------------------------------
  let interFlag = true
  if (!response.config.url.includes('modules/hospital/screenView/json/')) {
    try {
      // 拦截，进行姓名和身份证的解密
      replaceParam(response.data)
    } catch (err) {
      console.log(err)
    }
  }
  // 判断是否拦截
  for (let i = 0; i < noInterUrls.length; i++) {
    if (
      response.config.url === apiAddress[noInterUrls[i]] ||
      response.config.url.includes('modules/hospital/screenView/json/')
    ) {
      interFlag = false
    }
  }
  if (!interFlag) {
    return response.data
  }
  const isUnauth = response.data.code === 403 || response.data.code === 302
  if (response.config.url === apiAddress.realTimeMonitorOrgs && response.data.code === 0) {
    return response.data
  }
  if (response.data.code !== 0) {
    if (response.data.message) {
      notification.error({
        title: isUnauth ? '授权失败' : '提示',
        message: response.data.message,
        duration: 1000
      })
    }

    if (response.config.url === 'login.jspx' || response.config.url === 'common/allPermissionsForVue.jspx') {
      return response.data
    }

    return Promise.reject(new Error())
  } else {
    return response.data.data || {}
  }
}, err)

const installer = {
  vm: {},
  install (Vue) {
    Vue.use(VueAxios, service)
  }
}

export { installer as VueAxios, service as axios }
